Skip to content

fix(capsule): 终态/空闲让胶囊点击穿透,修复贴近输入框误触弹主界面 (#631)#633

Merged
H-Chris233 merged 1 commit into
betafrom
fix/issue-631-capsule-click-guard
Jun 10, 2026
Merged

fix(capsule): 终态/空闲让胶囊点击穿透,修复贴近输入框误触弹主界面 (#631)#633
H-Chris233 merged 1 commit into
betafrom
fix/issue-631-capsule-click-guard

Conversation

@appergb

@appergb appergb commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

User description

问题 (#631)

录音胶囊窗口为 220×110,远大于可见 pill(约 42px 高)。录音完成后胶囊有 2s toast 停留 + 360ms 离场动画,期间整个透明窗口区域仍响应点击。胶囊贴近输入框(如微信聊天窗)时,用户录完点击输入框易误触胶囊 → 激活 OpenLess → 主界面被带到前台,打断操作流。

修复

emit_capsule 的主线程闭包中按状态切换 set_ignore_cursor_events(这是胶囊状态变更的唯一漏斗):

  • Done / Cancelled / Error / Idle(含 toast 停留与离场动画期间)→ 点击穿透到下层应用
  • Recording / Transcribing / Polishing → 保持可点(✕/✓ 按钮)

按状态变化去重(AtomicBool swap),录音中 ~30Hz 电平帧不会重复调系统 API。Linux 分支本就不操作胶囊窗口(fcitx5 aux 文本),不受影响。

影响分析

GitNexus:emit_capsule 有 15 个直接调用方(dictation/QA/voice-agent 全部流程),hub 评级 CRITICAL。本改动不动签名、不动现有 show/hide/定位行为,仅附加一个状态驱动的窗口属性切换,对调用方透明。

验证

  • 新增单测 capsule_ignore_cursor_only_in_non_interactive_states(穿透状态映射契约)
  • cargo test --lib:479 passed, 0 failed

Closes #631


PR Type

Bug fix


Description

  • Add state-based cursor ignore for capsule window

  • Prevent misclick when capsule near input box

  • Add deduplication to avoid redundant system API calls

  • Add test for state mapping contract


Diagram Walkthrough

flowchart LR
  A["CapsuleState"] --> B{"Interactive?"}
  B -- "Recording, Transcribing, Polishing" --> C["No ignore (clickable)"]
  B -- "Done, Cancelled, Error, Idle" --> D["Ignore cursor events (click-through)"]
  C --> E["User can tap ✕/✓"]
  D --> F["Click passes to underlying app"]
Loading

File Walkthrough

Relevant files
Bug fix
capsule.rs
Implement state-based cursor ignore for capsule window     

openless-all/app/src-tauri/src/coordinator/capsule.rs

  • Added capsule_ignore_cursor_for_state() function to determine if
    capsule should ignore cursor based on state
  • Added static atomic CAPSULE_IGNORE_CURSOR_APPLIED for deduplication
  • In emit_capsule, set set_ignore_cursor_events only when state changes
+22/-0   
Tests
tests.rs
Add unit test for cursor ignore state mapping                       

openless-all/app/src-tauri/src/coordinator/tests.rs

  • Added test capsule_ignore_cursor_only_in_non_interactive_states to
    verify state to ignore mapping
  • Ensures Recording/Transcribing/Polishing are clickable; others are not
+13/-0   

胶囊窗口 220×110 远大于可见 pill,录音完成后 2s toast + 360ms 离场动画期间
透明区域仍会吃掉点击并激活 OpenLess(把主界面带到前台)。在 emit_capsule
主线程闭包按状态切换 set_ignore_cursor_events:Done/Cancelled/Error/Idle
点击穿透到下层应用;Recording/Transcribing/Polishing 保留 ✕/✓ 按钮可点。
按状态变化去重,录音中 ~30Hz 电平帧不重复调系统 API。Linux 分支不操作
胶囊窗口,不受影响。
@github-actions

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

631 - Partially compliant

Compliant requirements:

  • After recording, capsule disables click response (Done/Cancelled/Error/Idle states ignore cursor events).
  • During capsule disappear animation (toast and exit), no click response.

Non-compliant requirements:

  • Adjust capsule position to avoid overlap with input box (alternative approach not implemented).

Requires further human verification:

  • Note: the PR chooses to disable click penetration instead of repositioning; alternative requirement is not met but the core issue is addressed.
⏱️ Estimated effort to review: 1 🔵⚪⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@H-Chris233 H-Chris233 merged commit cffbd06 into beta Jun 10, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ui] 录音胶囊与输入框贴近时,完成后点击输入框易误触弹出主界面

2 participants